package com.md.api.filter;

import com.md.api.common.utils.RedisUtil;
import com.md.api.common.config.BaseConfig;
import com.md.api.common.config.RedisKeys;
import com.md.api.entity.HttpResult;
import com.md.api.common.utils.JsonUtils;
import com.md.api.common.utils.StringUtils;
import com.md.api.common.utils.TokenUtil;
import com.md.api.entity.SysUser;
import com.md.api.entity.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author xdd
 * @create 2020-04-09 10:25
 **/
@Slf4j
@Component
public class AccessApiInterceptor implements HandlerInterceptor {

    @Resource
    RedisUtil redisUtil;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info("开始拦截..."+request.getRequestURI());
        if (request.getRequestURI().startsWith("/test")){
            return true;
        }
        if (request.getRequestURI().contains("/file/upload")
                ||request.getRequestURI().contains("/test/resetFtpFile")
                ||request.getRequestURI().contains("/google/authorizingUrl")
                ||request.getRequestURI().contains("/google/authByCode")
                ||request.getRequestURI().contains("/face/getSign")
                ||request.getRequestURI().contains("/face/searchFace")
                ||request.getRequestURI().contains("/index/pictureShow")
                ||request.getRequestURI().contains("/index/picShow")
                ||request.getRequestURI().contains("/index/docInstruction")
                ||request.getRequestURI().contains("/index/evaluation")
                ||request.getRequestURI().contains("/index/phoneCode")
                ||request.getRequestURI().contains("/index/law")
                ||request.getRequestURI().contains("/sys/login")
                ||request.getRequestURI().contains("/pay/productNotify")
                ||request.getRequestURI().contains("/pay/shopCartNotify")
                ||request.getRequestURI().contains("/pay/rechargeNotify")
                ||request.getRequestURI().contains("/pay/vipNotify")
                ||request.getRequestURI().contains("/vip/list")
                ||request.getRequestURI().contains("/payment/return")
                ||request.getRequestURI().contains("/index/switchList")
                ||request.getRequestURI().contains("/message/sendSms")
                ||request.getRequestURI().contains("/message/sendEmail")
                ||request.getRequestURI().contains("/product/page")
                ||request.getRequestURI().contains("/product/recommend")
                ||request.getRequestURI().contains("/currentUser/register")
                ||request.getRequestURI().contains("/currentUser/login")
                ||request.getRequestURI().contains("/share/pictureList")
                ||request.getRequestURI().contains("/share/shareCoverImg")
                ||request.getRequestURI().contains("/share/shareDetail")
                ||request.getRequestURI().contains("/share/subAItimes")
                ||request.getRequestURI().contains("/product/spuDetail")
                ||request.getRequestURI().contains("/product/skuDetail")){
            return true;
        }

        if (request.getRequestURI().startsWith("/sys")){
            String client = request.getHeader("client");
            if (StringUtils.isEmpty(client)||!client.equalsIgnoreCase("admin")){
                writeJosnToResp(response, HttpResult.NO_AUTH);
                return false;
            }
            HttpResult result = HttpResult.NO_LOGIN;
            String  accessToken = request.getHeader("token");
            log.info("token:" + accessToken);
            if(StringUtils.isEmpty(accessToken)){
                writeJosnToResp(response, result);
                return false;
            }
            SysUser user = null;
            user = (SysUser)redisUtil.get(RedisKeys.getSysUserTokenInfoKey(accessToken));
            if (null==user){
                writeJosnToResp(response, result);
                return false;
            }
            long expire = redisUtil.getExpire(RedisKeys.getSysUserTokenInfoKey(accessToken));
            if (expire<3600*12) {
                redisUtil.expire(RedisKeys.getSysUserTokenInfoKey(accessToken), 3600*24);
            }
            return true;
        }

        HttpResult result = HttpResult.NO_LOGIN;
        String  accessToken = request.getHeader("token");
        log.info("token:" + accessToken);
        if(StringUtils.isEmpty(accessToken)){
            writeJosnToResp(response, result);
            return false;
        }
        UserInfo user = null;
        user = (UserInfo)redisUtil.get(RedisKeys.getUserTokenInfoKey(accessToken));
        if (null==user){
            writeJosnToResp(response, result);
            return false;
        }
        long expire = redisUtil.getExpire(RedisKeys.getUserTokenInfoKey(accessToken));
        if (expire<3600*12) {
            redisUtil.expire(RedisKeys.getUserTokenInfoKey(accessToken), 3600*24);
        }
        return true;
    }

    /**
     * 整个请求处理完毕回调方法，即在视图渲染完毕时回调，
     * 如性能监控中我们可以在此记录结束时间并输出消耗时间，
     * 还可以进行一些资源清理，类似于try-catch-finally中的finally，
     * 但仅调用处理器执行链中
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub

    }

    /**
     * 回写JSON数据
     *
     * @param response
     */

    private void writeJosnToResp(HttpServletResponse response, HttpResult resp) {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter pw = null;
        try {
            response.setStatus(200);
            pw = response.getWriter();
            log.info("回写响应数据:" + JsonUtils.toJsonString(resp));
            String resStr = JsonUtils.toJsonString(resp);
            pw.write(resStr);
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
    }


    public boolean isSpider(String hostname){
        List<String> spiders = BaseConfig.SPIDER;
        for (String spider : spiders) {
            if (hostname.toLowerCase().contains(spider)){
                return true;
            }
        }
        return false;
    }




}
